import * as THREE from 'three'
import {
  OrbitControls
} from 'three/examples/jsm/controls/OrbitControls.js';
import {
  OBJLoader
} from 'three/examples/jsm/loaders/OBJLoader';
import {
  MTLLoader
} from 'three/examples/jsm/loaders/MTLLoader';

import {
  GLTFLoader
} from 'three/examples/jsm/loaders/GLTFLoader'

import {
  FBXLoader
} from "three/examples/jsm/loaders/FBXLoader";

import {
  CSS3DRenderer,
  CSS3DObject,
  CSS3DSprite,

} from 'three/examples/jsm/renderers/CSS3DRenderer.js'

import {
  CSS2DRenderer,
  CSS2DObject
} from 'three/examples/jsm/renderers/CSS2DRenderer' // 引入包
import {
  MeshLambertMaterial,
  MeshPhongMaterial
} from 'three';

export default class ZThree {
  constructor(id) {
    this.id = id;
    this.el = document.getElementById(id);
  }

  // 初始化场景pointLight1
  initThree() {
    //    this.initRender(); //初始化场景渲染器
    //    this.initScene(); //加载场景容器
    //    this.initCamera(); //加载摄像机
    //    this.initLight(); //加载灯光
    //    this.initControls(); //鼠标操作镜头画面
    //    this.animate();
    // //加载gltf模型

    let _this = this;
    let width = this.el.offsetWidth;
    // let height = this.el.offsetHeight ? this.el.offsetHeight : window.innerHeight; //整体高度的算法
    let height = window.innerHeight; //整体高度的算法

    this.renderer = new THREE.WebGLRenderer({
      antialias: true,
      alpha: true
    })

    this.renderer.setPixelRatio(window.devicePixelRatio)
    this.renderer.setSize(width, height - 50)

    // this.renderer.outputEncoding = THREE.sRGBEncoding;
    this.el.append(this.renderer.domElement)
    // this.renderer.setClearColor('#ff0c44')
    this.renderer.shadowMap.enabled = true;




    this.scene = new THREE.Scene();
    this.camera = new THREE.PerspectiveCamera(45, width / height, 1, 3000)
    // this.camera.position.set(0,30,40)



    window.addEventListener('resize', function() {
      let tempheight = window.innerHeight - 50 //整体高度的算法
      _this.camera.aspect = _this.el.offsetWidth / tempheight;
      _this.camera.updateProjectionMatrix();
      // 保证同时更改即可。否则呗拉伸
      _this.renderer.setSize(_this.el.offsetWidth, tempheight);

      console.log('改变this.labelRenderer：', this.labelRenderer);
      // 2d文字渲染
      if (_this.labelRenderer) {

        _this.labelRenderer.setSize(_this.el.offsetWidth, tempheight);
        console.log(_this.el.offsetWidth, tempheight);
      }
    }, false)
  }

  // 初始化helper
  initHelper() {
    this.scene.add(new THREE.AxesHelper(100))
  }

  // 初始化控制器
  initOrbitControls() {
    let controls = new OrbitControls(this.camera, this.renderer.domElement)

    // 使动画循环使用时阻尼或自转 意思是否有惯性
    controls.enableDamping = true;
    //动态阻尼系数 就是鼠标拖拽旋转灵敏度
    //controls.dampingFactor = 0.25;
    //是否可以缩放
    controls.enableZoom = true;
    //是否自动旋转
    controls.autoRotate = false;
    controls.autoRotateSpeed = 0.3;
    //设置相机距离原点的最远距离
    controls.minDistance = 1;
    //设置相机距离原点的最远距离
    // controls.maxDistance = 1000;
    //是否开启右键拖拽
    controls.enablePan = true



    this.controls = controls
  }

  initLight() {
    this.directionalLight = new THREE.DirectionalLight('#fff')
    this.directionalLight.position.set(100, 100, 100).normalize()
    // this.scene.add(this.directionalLight)
    this.pointLight1 = new THREE.PointLight('#fff', 0.5)
    this.pointLight1.position.set(200, 200, 200)
    this.scene.add(this.pointLight1)


    let pointLight2 = new THREE.PointLight('#fff', 0.5)
    pointLight2.position.set(-200, 200, 200)
    this.scene.add(pointLight2)

    let pointLight3 = new THREE.PointLight('#fff', 0.5)
    pointLight3.position.set(-200, 200, -200)
    this.scene.add(pointLight3)

    let pointLight4 = new THREE.PointLight('#fff', 0.5)
    pointLight4.position.set(200, 200, -200)
    this.camera.add(pointLight4)
    // let ambientLight = new THREE.AmbientLight('#fff', 10)
    //  this.scene.add(ambientLight)
  }

  // 加载obj模型
  loaderObjModel(path, objName, mtlName) {
    return new Promise(resolve => {
      new MTLLoader()
        .setPath(path)
        .load(mtlName + '.mtl', function(materials) {

          materials.preload();

          // 加载obj
          new OBJLoader()
            .setPath(path)
            .setMaterials(materials)
            .load(objName + '.obj', function(object) {
              resolve(object)
            });
        });
    })
  }

  loadGLTFModel(url) {
    return new Promise(resolve => {
      const loader = new GLTFLoader();
      loader.load(url, function(gltf) {
        gltf.scene.position.set(0, 0, 0)
        gltf.scene.scale.set(20, 20, 20)
        gltf.scene.traverse(function(gltf) {
          // console.log(gltf.name);
          if (gltf.name == 'scence') {
            gltf.visible = false
          }

          if (gltf.isMesh) {
            // gltf.material=new MeshLambertMaterial({
            // 	map:gltf.material.map,
            // 	color:gltf.material.color
            // })

            gltf.frustumCulled = false;
            //模型阴影
            gltf.castShadow = true;


            //模型自发光
            // gltf.material.emissive = gltf.material.color;
            //  gltf.material.emissiveMap = gltf.material.map;
            // gltf.material.metalness = 0.5
            //  gltf.material.roughness = 0.5
            // gltf.material.shininess = 300
            // gltf.material.clearcoat = 1

            // gltf.material.side=THREE.DoubleSide

          }
        })

        resolve(gltf.scene)
      }, undefined, function(error) {
        console.error(error);
      });
    })
  }
  loadFBXModel(url) {
    return new Promise(resolve => {
      const loader = new FBXLoader();
      loader.load(url, function(obj) {
        obj.position.set(0, 0, 0)
        obj.scale.set(0.2, 0.2, 0.2)

        resolve(obj)
      }, undefined, function(error) {
        console.error(error);
      });
    })
  }

  // 加载天空盒
  loaderSky(path) {

    let skyTexture = new THREE.CubeTextureLoader().setPath(path).load([
      "posx.jpg", //右
      "negx.jpg", //左
      "posy.jpg", //上  model/skyBox/skyBox1/posy.jpg  model/skyBox/skyBox1/neg
      "negy.jpg", //下
      "posz.jpg", //前
      "negz.jpg" //后
    ]);

    this.scene.background = skyTexture;
    this.scene.background = new THREE.Color('#647373');
    // this.scene.background = new THREE.Color('#DEFEFF');
    this.renderer.setClearAlpha(1);

  }
  changeColor(meshObjList) {
    meshObjList.forEach(item => {
      item.modelObj.material.emissive.setHex((this.time * 8) % 2 > 1 ? item.color : item.color);
    })
  }
  changeTransparent(targetName, allObjList, opacity = 1, showMesh = true) {
    if (allObjList) {
      allObjList.forEach(item => {
        if (item.name != targetName) {
          item.traverse(T => {
            if (T.type == "Mesh") {
              T.material.opacity = opacity;
              T.material.transparent = true;
              T.material.visible = showMesh
            }
          })
        }
      })
    }

  }
  changeModelMeshVisible(allObjList, showMesh = true) {
    if (allObjList) {
      allObjList.forEach(item => {
        item.traverse(T => {
          if (T.type == "Mesh") {
            T.material.visible = showMesh
          }
        })
      })
    }
  }

  clearGroup(group) {
    const clearCache = (item) => {
      item.geometry.dispose();
      item.material.dispose();
    };
    const removeObj = (obj) => {
      let arr = obj.children.filter((x) => !!x);
      arr.forEach((item) => {
        if (item.children.length) {
          removeObj(item);
        } else {
          clearCache(item);
          item.clear();
        }
      });
      obj.clear();
      arr = null;
    };
    removeObj(group);
  this.scene.remove(group);
  }


  /* 绘制圆角矩形 */
  roundRect(ctx, x, y, w, h, r) {

    ctx.beginPath();
    ctx.moveTo(x + r, y);
    ctx.lineTo(x + w - r, y);
    ctx.quadraticCurveTo(x + w, y, x + w, y + r);
    ctx.lineTo(x + w, y + h - r);
    ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
    ctx.lineTo(x + r, y + h);
    ctx.quadraticCurveTo(x, y + h, x, y + h - r);
    ctx.lineTo(x, y + r);
    ctx.quadraticCurveTo(x, y, x + r, y);
    ctx.closePath();
    ctx.fill();
    ctx.stroke();

  }

  /* 创建字体精灵 */
  makeTextSprite(message, parameters) {

    if (parameters === undefined) parameters = {};

    var fontface = parameters.hasOwnProperty("fontface") ?
      parameters["fontface"] : "Arial";

    /* 字体大小 */
    var fontsize = parameters.hasOwnProperty("fontsize") ?
      parameters["fontsize"] : 18;

    /* 边框厚度 */
    var borderThickness = parameters.hasOwnProperty("borderThickness") ?
      parameters["borderThickness"] : 2;
    /* 字体边距 */
    let margins = parameters.hasOwnProperty("margin") ? parameters.margin : 10

    /* 创建画布 */
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');

    /* 字体加粗 */
    // context.font = "Bold " + fontsize + "px " + fontface;
    context.font = fontsize + "px " + fontface;
    /* 获取文字的大小数据，高度取决于文字的大小 */
    var metrics = context.measureText(message);

    var textWidth = metrics.width + margins * 2;

    /* 背景颜色 */
    context.fillStyle = parameters.hasOwnProperty("backgroundColor") ? parameters.backgroundColor :
      "rgba(255, 255, 255, 1.0)";

    /* 边框的颜色 */
    context.strokeStyle = parameters.hasOwnProperty("borderColor") ? parameters.borderColor :
      "rgba(0, 0, 0, 1.0)";
    context.lineWidth = borderThickness;

    /* 绘制圆角矩形 */
    this.roundRect(context, borderThickness / 2, borderThickness / 2, textWidth + borderThickness, fontsize *
      1.4 + borderThickness + 2 * margins, 3);

    /* 字体颜色 */
    context.fillStyle = parameters.hasOwnProperty("fontColor") ? parameters.fontColor : "rgba(0, 0, 0, 1.0)";
    context.fillText(message, borderThickness + margins, fontsize + borderThickness + margins);

    /* 画布内容用于纹理贴图 */
    var texture = new THREE.Texture(canvas);
    texture.needsUpdate = true;

    var spriteMaterial = new THREE.SpriteMaterial({
      map: texture,
      transparent: true
    });
    var sprite = new THREE.Sprite(spriteMaterial);

    /* 缩放比例 */
    sprite.scale.set(8, 4, 0);

    return sprite;

  }




}
